#ifndef EXCEPTION_HH_
# define EXCEPTION_HH_
# include <stdexcept>
# include <string>
# include <QtCore>

# define EXCEPTION(CLASS, PARENT, CTOR)                                 \
    class CLASS: public PARENT {                                        \
        public:                                                         \
        explicit CLASS(std::string const& msg = ""): CTOR(msg) {}       \
                                                                        \
        public:                                                         \
        explicit CLASS(char const* msg): CTOR(std::string(msg)) {}      \
                                                                        \
        public:                                                         \
        explicit CLASS(QString const& msg): CTOR(msg.toStdString()) {}  \
    }                                                                   \

# define EX(CLASS, PARENT) EXCEPTION(CLASS, PARENT, PARENT)

EXCEPTION(NetworkError, std::runtime_error, runtime_error);
EXCEPTION(ProtocolError, std::runtime_error, runtime_error);
EX(NonFatalProtocolError, ProtocolError);
EXCEPTION(UserNotFoundError, std::runtime_error, runtime_error);
EXCEPTION(ServerInitError, std::runtime_error, runtime_error);
EXCEPTION(WorldException, std::runtime_error, runtime_error);
EXCEPTION(SetPlayerException, std::logic_error, logic_error);
EX(UserDeletedException, WorldException);
EX(GalaxyNotFoundException, WorldException);
EX(GalaxyExistsException, WorldException);
EX(GalaxyFullException, WorldException);
EX(GameStartedException, WorldException);
EX(UserNotFoundException, WorldException);
EX(UserExistsException, WorldException);
EX(PlayerNotFoundException, WorldException);
EX(PlayerExistsException, WorldException);
EX(NullPointerException, WorldException);

class FleetNotFound: public WorldException {
    public:
    explicit FleetNotFound(u8 id):
        WorldException("Fleet not found: " + QString::number(id)) {}
};

# undef EXCEPTION
# undef EX

#endif /* EXCEPTION_HH_ */
